﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using AlgorithmResult;
using PermutationCl;

namespace TripletSegmentationGUI
{
    public class DataTableResult
    {

        DataTable table;
        public const string STR_Index = "Index";
        public const string STR_Codon = "Codon";
        public const string STR_SumOfTripletsExpansion = "Sum of triplets expansion";
        public const string STR_NumberOfFragments = "Number of fragments";
        public const string STR_AverageFragmentLength = "Avg fragment length";
        public const string STR_AverageFragmentSimilarity = "Avg fragment similarity rate(%)";
        public const string STR_AverageContributionLength = "Avg contribution length rate(%)";
        public const string STR_AverageSimilarityStrengthRate = "Similarty strength rate(%)";
        public const string STR_AverageLengthStrengthRate = "Length strength rate(%)";

        public const string STR_BoundaryIndexes = "Boundary Indexes";
        Dictionary<String, int> codonMap = new Dictionary<string, int>();

        public Dictionary<String, int> CodonMap
        {
            get { return codonMap; }
            set { codonMap = value; }
        }
        public DataTable Table
        {
            get { return table; }
            set { table = value; }
        }

        public DataTable CreateDataTable(Result algresult, int[] _codonSize)
        {
            CreateDataTableColumns();
            InitTable(_codonSize);
            FillData(algresult, algresult.BoundariesSet);
            return table;
        }

        private void FillData(Result algresult, long[] boundariesSet)
        {
            int tripletIndex = -1;
            for (int i = 0; i < algresult.NumOfBoundaries; ++i)
            {
                tripletIndex = codonMap[algresult.ArchreTriplets[i]];

                if (table.Rows[tripletIndex][STR_NumberOfFragments]==null)
                    table.Rows[tripletIndex][STR_NumberOfFragments] = 1;
                else
                {
                    table.Rows[tripletIndex][STR_NumberOfFragments] = (int)table.Rows[tripletIndex][STR_NumberOfFragments] + 1;

                }
                long segmentLength = 0;
                if (i == 0)
                {
                    segmentLength=  boundariesSet[i];
                    table.Rows[tripletIndex][STR_SumOfTripletsExpansion]=segmentLength;
#if NDEBUG
                    table.Rows[tripletIndex][STR_BoundaryIndexes] += String.Format("0-{0},\n", boundariesSet[i]-1);
#endif                 
                }
                else
                {
                    segmentLength =  (boundariesSet[i] - boundariesSet[i - 1]);
 #if NDEBUG
                    table.Rows[tripletIndex][STR_BoundaryIndexes] += String.Format("{0}-{1},\n", boundariesSet[i - 1], boundariesSet[i]-1);
#endif
                    table.Rows[tripletIndex][STR_SumOfTripletsExpansion] = (long)(table.Rows[tripletIndex][STR_SumOfTripletsExpansion]) + segmentLength;
                }
                double tripletLength = (long)(table.Rows[tripletIndex][STR_SumOfTripletsExpansion]);
                double numOfFragments = (int)(table.Rows[tripletIndex][STR_NumberOfFragments]);
                (table.Rows[tripletIndex][STR_AverageFragmentLength]) = (double)(tripletLength / numOfFragments);
                float similarity = algresult.SimilarityToAncientCodon[i];


                (table.Rows[tripletIndex][STR_AverageContributionLength]) = (float)(tripletLength / algresult.Text.Length)*100;// (float)(((float)table.Rows[tripletIndex][STR_AverageContributionLength] / 100 + (float)(segmentLength / tripletLength))/numOfFragments) * 100;
                (table.Rows[tripletIndex][STR_AverageFragmentSimilarity]) = (float)(((float)table.Rows[tripletIndex][STR_AverageFragmentSimilarity]+ similarity));

               // (table.Rows[tripletIndex][STR_AverageSimilarityStrengthRate]) = (float)((float)(table.Rows[tripletIndex][STR_AverageContributionLength]) * (float)(table.Rows[tripletIndex][STR_AverageFragmentSimilarity]))/100;

         //       (table.Rows[tripletIndex][STR_AverageLengthStrengthRate]) = (float)((float)(table.Rows[tripletIndex][STR_AverageContributionLength]) * (double)(table.Rows[tripletIndex][STR_AverageFragmentLength])) / 100;
            }
            for (int i = 0; i < table.Rows.Count; ++i)
            {
                if ((int)(table.Rows[i][STR_NumberOfFragments]) != 0)
                {
                    (table.Rows[i][STR_AverageFragmentSimilarity]) = (float)(((float)table.Rows[i][STR_AverageFragmentSimilarity]) / (int)(table.Rows[i][STR_NumberOfFragments])) * 100;
                    (table.Rows[i][STR_AverageSimilarityStrengthRate]) = (float)((float)(table.Rows[i][STR_AverageContributionLength]) * (float)(table.Rows[i][STR_AverageFragmentSimilarity])) / 100;
                    (table.Rows[i][STR_AverageLengthStrengthRate]) = (float)((float)(table.Rows[i][STR_AverageContributionLength]) * (double)(table.Rows[i][STR_AverageFragmentLength])) / 100;
         
                }
            }
        }
        private DataTable CreateDataTableColumns()
        {
            // Create an empty table.
            table = new DataTable("ResultTable");

            // Add  columns to the table.
           

            table.Columns.Add(STR_Index, typeof(Int32));
            table.Columns.Add(STR_Codon, typeof(String));
            table.Columns.Add(STR_SumOfTripletsExpansion, typeof(long));
            table.Columns.Add(STR_NumberOfFragments, typeof(Int32));
            table.Columns.Add(STR_AverageFragmentLength, typeof(double));
            table.Columns.Add(STR_AverageFragmentSimilarity, typeof(float));
            table.Columns.Add(STR_AverageContributionLength, typeof(float));
            table.Columns.Add(STR_AverageSimilarityStrengthRate, typeof(float));
            table.Columns.Add(STR_AverageLengthStrengthRate, typeof(float));
            table.Columns.Add(STR_BoundaryIndexes, typeof(String));

            // Add data rows to the table.

           

            return table;
        }

        private void InitTable(int[] codonsRange)
        {
           
            int index = 0;
            string[] nucls = Enum.GetNames(typeof(CodonSegDP.NUCLEOTID));

            for (int i = 0; i < codonsRange.Length; i++)
            {


                Variations<string> variations = new Variations<string>(nucls, codonsRange[i], GenerateOption.WithRepetition);
                String codonName = String.Empty;
                DataRow row = null;
                foreach (IList<string> v in variations)
                {
                    codonName = String.Empty;
                    row = table.NewRow();
                    row[STR_Index] = index;
                    for (int j = 0; j < codonsRange[i]; ++j)
                    {
                        codonName += (String)(v[j]);

                    }
                    row[STR_Codon] += codonName;
                    row[STR_SumOfTripletsExpansion] = 0;
                    row[STR_NumberOfFragments] = 0;
                    row[STR_AverageFragmentLength] = 0;
                    row[STR_AverageFragmentSimilarity] = 0;
                    row[STR_AverageContributionLength] = 0;
                    row[STR_AverageSimilarityStrengthRate] = 0;
                    row[STR_AverageLengthStrengthRate] = 0;
                    row[STR_BoundaryIndexes] = String.Empty;

                    codonMap[codonName] = index;
                    index++;
                    table.Rows.Add(row);
                }

            }

        }
    }
}
